{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ab43768c-5f6c-4575-831f-d2c764252293",
   "metadata": {},
   "source": [
    "Mistral demo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "959298e5-d092-424c-af15-c75fad84b877",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Name: langchain\n",
      "Version: 0.1.9\n",
      "Summary: Building applications with LLMs through composability\n",
      "Home-page: https://github.com/langchain-ai/langchain\n",
      "Author: \n",
      "Author-email: \n",
      "License: MIT\n",
      "Location: /opt/conda/lib/python3.11/site-packages\n",
      "Requires: aiohttp, dataclasses-json, jsonpatch, langchain-community, langchain-core, langsmith, numpy, pydantic, PyYAML, requests, SQLAlchemy, tenacity\n",
      "Required-by: \n"
     ]
    }
   ],
   "source": [
    "!pip show langchain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "fe91c75c-ec85-4660-bc4c-9b193c9f2433",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Name: pydantic\n",
      "Version: 1.10.13\n",
      "Summary: Data validation and settings management using python type hints\n",
      "Home-page: https://github.com/pydantic/pydantic\n",
      "Author: Samuel Colvin\n",
      "Author-email: s@muelcolvin.com\n",
      "License: MIT\n",
      "Location: /opt/conda/lib/python3.11/site-packages\n",
      "Requires: typing-extensions\n",
      "Required-by: docarray, langchain, langchain-core, langsmith, openai\n"
     ]
    }
   ],
   "source": [
    "# Make sure pydantic==1.10.13 is used to avoid pydantic validation error due to compatability issue with langchain\n",
    "\n",
    "!pip show pydantic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ec70e220-f276-4981-b5bc-bb00007dd748",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "ollama_url = \"http://ollama:11434\"\n",
    "\n",
    "model_name = \"mistral:instruct\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6483fe73-0aa2-47bd-af60-a21d19cbb320",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.llms import Ollama\n",
    "\n",
    "llm = Ollama(base_url=ollama_url,model=model_name)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "80345aa8-f679-48cf-80fb-438cdb6e7f94",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.embeddings.ollama import OllamaEmbeddings\n",
    "embeddings = OllamaEmbeddings(base_url=ollama_url, model=model_name)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "d597fa2b-21c6-4127-8af2-fb7a126bbd25",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.output_parsers import StrOutputParser\n",
    "\n",
    "output_parser = StrOutputParser()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bf30b7e-f7f9-4bf8-b02c-a570e5e5a5d6",
   "metadata": {},
   "source": [
    "\n",
    "# Sample to directly ask question to LLM\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "f9b38fcd-8a9c-487c-aee1-5dae29d08841",
   "metadata": {},
   "outputs": [],
   "source": [
    "chain = llm | output_parser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "ab8d7b0f-8894-4913-8e4d-0cad52f07004",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' Structurizr is a set of open source tools for creating, documenting, and sharing software architecture descriptions. It was developed by Chris Young as part of the Archi family of modeling tools, which also includes Archi (a UML modeling tool) and Archimate (a tool for creating and documenting architectural models using the Archimate language).\\n\\nStructurizr provides a web-based interface for creating diagrams and visualizing software architecture, using a variety of notations including Architecture Description Language (ADL), UML, and Archi- and Archimate-specific notations. It supports creating diagrams at different levels of abstraction, from high-level overviews to detailed implementation diagrams.\\n\\nStructurizr also provides features for sharing models and diagrams with others, as well as integrating with other tools and services such as GitHub, JIRA, and Confluence. It is often used in Agile and DevOps contexts to help teams communicate and understand software architecture throughout the development process.'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\"what is structurizr\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2bf4d410-7ecd-424f-bc59-19f546d48bc0",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "# Sample to use chat prompt templates\n",
    "\n",
    "With a better context provided to LLM.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c44c597e-48ac-40fb-b3f5-a387f05182d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "prompt = ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"You are a world class software architecture designer with knowledage of structurizr\"),\n",
    "    (\"user\", \"{input}\")\n",
    "])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "10154e23-c62f-400f-aa4a-6aee0b33c064",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.runnables import RunnableParallel, RunnablePassthrough\n",
    "\n",
    "retrieval = RunnableParallel(\n",
    "    {\"input\": RunnablePassthrough()}\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ad7b6b6b-8174-4cc3-8c33-7e4a358b6f05",
   "metadata": {},
   "outputs": [],
   "source": [
    "chain = retrieval | prompt | llm | output_parser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9ab35ccb-f927-4960-addd-f2c640805707",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' Structurizr is not a software itself, but rather a modeling tool and set of related tools for creating, documenting, and discussing software architectures. It was developed by Chris Young to help design, document, and discuss software architecture in a simple way.\\n\\nThe main tool in the Structurizr suite is the \"Model-driven Architecture (MDA) Workbench,\" which is an Eclipse RCP application that supports creating and editing various types of models:\\n\\n1. **Component Diagrams**: They represent the decomposition of your application into components, including the relationships between them.\\n2. **Container Diagrams**: They model the deployment of your components to different runtimes (like Docker containers or VMs).\\n3. **Process Diagrams**: They model business processes, helping you understand how your software supports the business.\\n4. **Relationship Overview Diagrams**: They provide an overview of relationships between all diagrammed components, allowing you to see the big picture.\\n\\nThe tool also includes integration with other tools like PlantUML and Graphviz for creating visualizations of your models. This makes it easier to discuss and communicate architectural decisions with stakeholders or team members.'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\"what is structurizr?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "c536e351-994a-4831-84e1-83e611ac1c39",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' I\\'d be happy to help you get started with Structurizr DSL (Domain Specific Language), which is used for creating and documenting software architecture models. In this example, we will create a simple architecture model using Structurizr DSL.\\n\\nFirst, let\\'s define some context: Our example architecture consists of three main components: `BookShop`, `OrderService`, and `PaymentGateway`. These components interact with each other as follows:\\n\\n1. The `BookShop` component manages a catalog of books and handles user requests to place orders for those books.\\n2. The `OrderService` component processes the order details and creates new orders in the system.\\n3. The `PaymentGateway` component is responsible for processing payment transactions and confirming the order once it\\'s paid for.\\n\\nNow, let\\'s write the Structurizr DSL code to create this architecture model:\\n\\n```ruby\\n# Define a new Software System\\nsystem \"BookShop\" do\\n  # Define the components\\n  component \"BookShop\" do\\n    makes \"Manages catalog of books and handles user requests to place orders for those books.\"\\n  end\\n\\n  component \"OrderService\" do\\n    makes \"Processes order details and creates new orders in the system.\"\\n\\n    # Define a relationship from BookShop to OrderService\\n    uses_component \"BookShop\"\\n  end\\n\\n  component \"PaymentGateway\" do\\n    makes \"Processes payment transactions and confirms the order once it\\'s paid for.\"\\n\\n    # Define relationships from OrderService and PaymentGateway\\n    uses_component \"OrderService\"\\n  end\\nend\\n```\\n\\nThis DSL code creates a new software system called `BookShop` and defines its three components with their respective roles. We also define the relationships between the components, indicating that both `OrderService` and `PaymentGateway` use the `BookShop` component.\\n\\nAfter writing this code, you can run Structurizr to generate a visualization of your architecture model in various formats (e.g., PNG, PDF, SVG) or export it as C4 diagrams, Mermaid diagrams, ArgoWorkflow Templates, and more.'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\"please provide example of structurizr dsl\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "51464ac6-3318-4d8e-bf64-2874f8febdb9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\" I cannot definitively answer that question as I don't have the ability to access the specific details of Company XYZ or their technology stack. Structurizr is a modeling toolset for designing software architecture and documenting it using simple, clear, and concise diagrams. It doesn't force any particular DSL (Domain Specific Language) but rather provides a set of templates that can be used with popular DSLs like PlantUML, Mermaid, or DIA Graphviz. It is up to the user or organization to choose which DSL they prefer and use with Structurizr.\""
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\"Does company XYZ use structurizr dsl\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62a36647-c343-413f-9e77-4767bad54d39",
   "metadata": {},
   "source": [
    "\n",
    "# RAG Search Example\n",
    "\n",
    "https://python.langchain.com/docs/expression_language/get_started#rag-search-example\n",
    "\n",
    "Requires:\n",
    "pip install docarray tiktoken pydantic==1.10.13"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "2ef8f446-fbe6-4163-9cbd-fa70b6775b9c",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.vectorstores import DocArrayInMemorySearch\n",
    "\n",
    "# https://docs.structurizr.com/\n",
    "vectorstore = DocArrayInMemorySearch.from_texts(\n",
    "    [\"\"\"\n",
    "    Structurizr builds upon \"diagrams as code\", allowing you to create multiple software architecture diagrams from a single model. \n",
    "    There are a number of tools for creating Structurizr compatible workspaces, with the Structurizr DSL being the recommended option for most teams.\n",
    "    \"\"\", \"\"\"\n",
    "    Structurizr builds upon \"diagrams as code\", allowing you to create multiple software architecture diagrams, in a variety of rendering tools, from a single model.\n",
    "    \"\"\",\n",
    "    \"Structurizr is a modelling tool, allowing you to create multiple diagrams from a single model.\",\n",
    "    \"\"\"\n",
    "    As an example, the following Structurizr DSL can be used to create a software architecture model and an associated view that describes a frontline staff using the \"MyWorkspace\" software system.\n",
    "    ---\n",
    "    workspace {\n",
    "\n",
    "        model {\n",
    "            user = person \"frontline staff\"\n",
    "            softwareSystem = softwareSystem \"MyWorkspace\"\n",
    "    \n",
    "            user -> softwareSystem \"Uses\"\n",
    "        }\n",
    "    \n",
    "        views {\n",
    "            systemContext softwareSystem {\n",
    "                include *\n",
    "                autolayout lr\n",
    "            }\n",
    "        }\n",
    "        \n",
    "    }\n",
    "    ---\n",
    "    \"\"\",\n",
    "    \"Some famous companies such as ABC and XYZ are using Structurizr DSL for software architecture modeling and documentation.\",],\n",
    "    embedding=embeddings,\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "4e3ecf98-abe2-427a-817e-7659100cb5aa",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "retriever = vectorstore.as_retriever()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "6c3124c5-14c7-4432-a0b8-8406bc44bac9",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.runnables import RunnableParallel, RunnablePassthrough\n",
    "\n",
    "retrieval = RunnableParallel(\n",
    "    {\"context\": retriever, \"input\": RunnablePassthrough()}\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "1f888ce1-8976-4c0c-80ce-2f7076ebd7f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "\n",
    "prompt = ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"\"\"You are a world class software architecture designer with knowledage of structurizr in the following context:\n",
    "    {context}\n",
    "\n",
    "    Please answer the question in the above context only, please do not make up anything if you do not know the answer.\n",
    "    \"\"\"),\n",
    "    (\"user\", \"{input}\")\n",
    "])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "1619ca62-9f50-4468-8ab5-8c40f0984076",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "chain = retrieval | prompt | llm | output_parser\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "728e10f3-0c16-4e3b-8538-4026eef5e942",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' Structurizr is a modeling tool used for creating software architecture models and documentation. It builds upon the concept of \"diagrams as code,\" allowing multiple software architecture diagrams to be generated from a single model. The recommended way to create Structurizr compatible workspaces is by using the Structurizr DSL (Domain Specific Language). This DSL can be used to define a software architecture model and its associated views, such as a system context view for a frontline staff using a software system named \"MyWorkspace.\"'"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\"what is structurizr?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "8723909b-c331-4b6f-b348-b470c421b193",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' I\\'d be happy to help you understand Structurizr DSL (Domain Specific Language) with an example based on the information provided in the context.\\n\\nStructurizr DSL is a language used for modeling software architecture and creating diagrams as code. Let\\'s consider a simple example of a multi-tiered web application using Structurizr DSL:\\n\\n```ruby\\n# Define the architecture model\\nmodel \"My Application\" do\\n  # Define the components\\n  component \"Database\" do\\n    tags :technology => \"PostgreSQL\", :layer => \"database\"\\n    ports { in port \"Data Input/Output\" }\\n  end\\n\\n  component \"Web Server\" do\\n    tags :technology => \"Apache HTTP Server\", :layer => \"web\"\\n    ports {\\n      in port \"HTTP Request\" { interfaces :http },\\n      out port \"HTTP Response\"\\n    }\\n    dependencies {\\n      depends_on Database\\n    }\\n  end\\n\\n  component \"Application Logic\" do\\n    tags :technology => \"Ruby on Rails\", :layer => \"application logic\"\\n    ports { in port \"Request Input\" { interfaces :http }, out port \"Response Output\" }\\n    dependencies {\\n      depends_on Web Server\\n    }\\n  end\\n\\n  component \"Load Balancer\" do\\n    tags :technology => \"NGINX\", :layer => \"load balancer\"\\n    ports { in port \"HTTP Request In\", out port \"HTTP Response Out\" }\\n    dependencies {\\n      depends_on Web Server, Application Logic\\n    }\\n  end\\nend\\n```\\n\\nThis example defines a simple web application with a database, a web server (Apache HTTP Server), an application logic layer (Ruby on Rails), and a load balancer (NGINX). Each component is defined using the `component` keyword, with its technology, tags, ports, dependencies, and any other relevant properties specified as needed.\\n\\nThe model can be saved as a single .adoc file or multiple files depending on your preference and project organization. Once the model is created, you can generate diagrams from it using various rendering tools like PlantUML, Mermaid, or Graphviz, among others. This ensures that your architecture documentation remains consistent with the underlying codebase and can be easily updated as the application evolves.'"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\"please provide example of structurizr dsl\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "6074f2a1-637e-4c66-a4d6-be968f3a0f01",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' Based on the context provided in the documents, it is mentioned that \"some famous companies such as ABC and XYZ are using Structurizr DSL for software architecture modeling and documentation.\" Therefore, according to the information given, it can be inferred that yes, company XYZ uses Structurizr DSL.'"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\"Does company XYZ use structurizr dsl\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "dae9d771-4c58-4427-a4aa-94446ade35a8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' According to the provided context, some famous companies such as ABC and XYZ are using Structurizr DSL for software architecture modeling and documentation. However, the text does not provide a list of all the companies using Structurizr DSL.'"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\"what companies are using structurizr dsl\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "d7dfb6b3-faa4-48e2-9efe-2c88dba6b479",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' Based on the context provided, here is an example of Structurizr DSL related to the software system named \"MyWorkspace\":\\n\\n```markdown\\n workspace \"MyWorkspaceWorkspace\" {\\n    model {\\n        softwareSystem = softwareSystem \"MyWorkspace\"\\n        // Add other components if needed, e.g., users, databases, etc.\\n    }\\n\\n    views {\\n        systemContext softwareSystem {\\n            // Configure the view as needed, e.g., enable automatic layout\\n            include *\\n            autolayout lr\\n        }\\n    }\\n}\\n```\\n\\nThis DSL creates a new workspace called \"MyWorkspaceWorkspace\" that contains a single software system named \"MyWorkspace\". The `systemContext` view for the software system is also configured with an automatic layout. You can extend this example by adding other components such as users, databases, and their relationships to the software system.'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\"\"\"\n",
    "please provide example of structurizr dsl related to software system \"MyWorkspace\"\n",
    "\"\"\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
